package Database;


import java.util.List;
import java.util.logging.Level;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

import Logger.StompLogger;


public class LoginHandler 
{
	private SessionFactory _factory;
	private TripleDES _tripleDes;
	//-------------------------------------------Constructors-----------------------------------------

	public LoginHandler()
	{
		_tripleDes = new TripleDES("4d99g13j5j91j27c512ji69373y788r6");
		AnnotationConfiguration config = new AnnotationConfiguration();
		config.addAnnotatedClass(LoginInformation.class);
		config.configure("hibernate.cfg.xml");
		_factory = config.buildSessionFactory();
		//creating new schema
		new SchemaExport(config).create(true,true);
		addNewLogin("manager", "manager");
	}

	//-------------------------------------------private funcs-----------------------------------------

	//returns the object of the login of nick, and null if not exist
	private synchronized LoginInformation exists(String nick)
	{
		LoginInformation user = null;
		Session session = _factory.getCurrentSession();
		session.beginTransaction();
		Query query = session.createQuery("from LoginInformation where nick = :name"); 
		//in hibernate the query must have the name of the class after from and not the name of the table!
		query.setString("name", nick);
		List infoList = query.list();
		if (!infoList.isEmpty()){
			user = (LoginInformation) infoList.get(0);
		}
		session.getTransaction().commit();
		return user;
	}

	//-------------------------------------------public funcs-----------------------------------------


	public synchronized boolean addNewLogin(String nick, String pass)
	{

		LoginInformation loginInf = exists(nick);
		if(loginInf != null){
			return false;
		}
		else
		{	
			Session session = _factory.getCurrentSession();
			session.beginTransaction();
			LoginInformation user = new LoginInformation();
			user.setNick(nick);
			user.setPass(_tripleDes.encrypt(pass));
			user.setActive(true);
			session.save(user);
			session.getTransaction().commit();
			StompLogger.write(Level.INFO,"added new login: " + nick + " to the database");

			return true;
		}
	}

	public synchronized boolean checkPassword(String nick, String pass)
	{
		LoginInformation loginInf = exists(nick);
		if(loginInf == null || !(_tripleDes.decrypt(loginInf.getPass())).equals(pass))
		{
			System.out.println("stack here!!!!!");
			return false;
		}
		else
			return true;
	}

	public synchronized void removeLogin(String nick)
	{
		//System.out.println("removing user "+ nick);
		//if(checkPassword(nick, _tripleDes.encrypt(pass)))
			
				LoginInformation loginInf = exists(nick); 
				if(loginInf!=null){
					if(loginInf.isActive()){
						try{
							Session session = _factory.getCurrentSession();
							session.beginTransaction();
							loginInf.setActive(false);
							session.update(loginInf);
							session.getTransaction().commit();
							StompLogger.write(Level.INFO,"removing login of user: " + nick+ " by changing to Not Active in DB" );
						}
						catch(HibernateException e){
							StompLogger.write(Level.INFO,"couldn't remove login of user: " + nick );
							e.printStackTrace();
						}
					}
					else{
						StompLogger.write(Level.INFO,"error in removed login: " + nick + " user already not active");
					}
				}
				else{
					StompLogger.write(Level.INFO,"error in removed login: " + nick + " user not in the database");
				}		
	}

	public boolean checkIfAvailable(String name) 
	{
		LoginInformation loginInf = exists(name);
		if(loginInf == null){
			return true;
		}
		return false;
	}
	
	public boolean checkIfActive(String name) 
	{
		LoginInformation loginInf = exists(name);
		if(loginInf == null){
			return false;
		}
		else 
			return loginInf.isActive();
			
		
	}

}
